package com.service.scheduling.task;

import cn.hutool.core.date.DateTime;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.service.dao.enums.CoinsEnum;
import com.service.dao.model.Coins;
import com.service.dao.model.CoinsPrice;
import com.service.dao.model.SysQuotesIpfx;
import com.service.scheduling.constants.IPFSConstant;
import com.service.scheduling.dto.IPFXConfigVo;
import com.service.scheduling.service.CoinService;
import com.service.scheduling.service.CoinsPriceService;
import com.service.scheduling.service.SysQuotesIpfxService;
import com.service.scheduling.utils.MemCacheNoTran;
import io.micrometer.core.instrument.util.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.jsoup.Jsoup;
import org.jsoup.nodes.*;
import org.jsoup.select.Elements;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;

import java.math.BigDecimal;
import java.util.Date;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Slf4j
@Component
public class IPFXInfoTask {
	@Autowired
	private MemCacheNoTran memCache;
	@Autowired
	private CoinsPriceService coinsPriceService;
	@Autowired
	private CoinService coinService;
	@Autowired
	private SysQuotesIpfxService sysQuotesIpfxService;

	/**
	 * 每3分钟执行一次更新到缓存
	 */
	@Scheduled(cron = "0 */5 * * * ?")
	public void iPFSInfoTask() {
		log.info("FIL更新网络任务-开始");
		try {
			Document doc = Jsoup.connect("https://filfox.info/zh").get();
			Element e = doc.body();
			Elements elements = e.getElementsByClass("lg:mb-6");
			SysQuotesIpfx config = new SysQuotesIpfx();
			for (Element element : elements) {
				Elements textEl = element.getElementsByClass("text-gray-500");
				String text = null;
				String val = null;
				if (!textEl.isEmpty()) {
					text = textEl.get(0).text();
				}
				Elements valEl = element.getElementsByClass("items-start");
				if (!valEl.isEmpty()) {
					val = valEl.get(0).text();
				}
				this.initConfig(text, val, config);
			}
			String json = JSONObject.toJSON(config).toString();
			//添加/更新到redis缓存
			memCache.setNoExpire(IPFSConstant.REDIS_IPFS_KEY, json);
		} catch (Exception e) {
			e.printStackTrace();
			log.error("FIL更新网络任务-出错 {}",e.getMessage());
		}
		log.info("FIL更新网络任务-结束");
	}

	/**
	 * 每30分钟执行一次添加到数据库
	 */
	@Scheduled(cron = "0 */30 * * * ?")
	public void iPFSInfoHoursTask() {
		try {
			//缓存读取filFox全网数据
			SysQuotesIpfx IPFXConfig = JSONObject.parseObject(memCache.get(IPFSConstant.REDIS_IPFS_KEY), SysQuotesIpfx.class);
			//每个小时执行一次添加到数据库
			if (ObjectUtils.isEmpty(IPFXConfig)) {
				iPFSInfoTask();
				iPFSInfoHoursTask();
			}
			SysQuotesIpfx databaseConfig = sysQuotesIpfxService.getOne(new QueryWrapper<SysQuotesIpfx>().lambda()
					.orderByDesc(SysQuotesIpfx::getUpdateTime)
					.last("limit 1")
			);
			BeanUtils.copyProperties(IPFXConfig, databaseConfig);
			sysQuotesIpfxService.updateById(databaseConfig);
			Coins coins = coinService.getByCoinsName(CoinsEnum.FIL.getName());
			BigDecimal lastPrice = new BigDecimal(IPFXConfig.getLastPrice().replace("$ ", ""));
			BigDecimal dailyOutRate = new BigDecimal(IPFXConfig.getPer_24h_rewards().replace(" FIL/TiB", ""));

			coins.setOutputNum(dailyOutRate);
			coinService.updateById(coins);//更新币当前产出单量
			CoinsPrice coinsPrice = CoinsPrice.builder()
					.coinPrice(lastPrice)
					.standardPrice(lastPrice).build();
			//新增数据库FIL价格记录
			coinsPriceService.update(coinsPrice, new QueryWrapper<CoinsPrice>().lambda()
					.eq(CoinsPrice::getCoinsName, CoinsEnum.FIL.getName()));
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private SysQuotesIpfx initConfig(String text, String val, SysQuotesIpfx vo) {
		try {
			if (StringUtils.isNotEmpty(text)) {
				switch (text) {
					case IPFSConstant
							.BLOCK_NUM_TEXT:
						vo.setBlockNum(val);
						break;
					case IPFSConstant
							.LAST_TIME_TEXT:
						vo.setLastTime(getNumber(val));
						break;
					case IPFSConstant
							.TOTAL_HASHRATE_TEXT:
						vo.setTotalHashRate(val);
						break;
					case IPFSConstant
							.ACTIVE_MINERS_TEXT:
						vo.setActiveMiners(val);
						break;
					case IPFSConstant
							.PER_REWARDS_TEXT:
						vo.setPerRewards(val);
						break;
					case IPFSConstant
							.PER_24H_REWARDS_TEXT:
						vo.setPer_24h_rewards(val);
						break;
					case IPFSConstant
							.TOTAL_24H_DIGS_TEXT:
						vo.setTotal_24h_digs(val);
						break;
					case IPFSConstant
							.CURR_PLEDGE_NUM_TEXT:
						vo.setCurrPledgeNum(val);
						break;
					case IPFSConstant
							.TOTAL_PLEDGE_NUM_TEXT:
						vo.setTotalPledgeNum(val);
						break;
					case IPFSConstant
							.TOTAL_24H_MESSAGE_TEXT:
						vo.setTotal_24h_message(val);
						break;
					case IPFSConstant
							.TOTAL_FLUX_NUM_TEXT:
						vo.setTotalFluxNum(val);
						break;
					case IPFSConstant
							.TOTAL_ACCOUNTS_TEXT:
						vo.setTotalAccounts(val);
						break;
					case IPFSConstant
							.PER_BLOCK_TIMES_TEXT:
						vo.setPerBlockTimes(val);
						break;
					case IPFSConstant
							.PER_BLOCK_NUM_TEXT:
						vo.setPerBlockNum(val);
						break;
					case IPFSConstant
							.ADD_MECHANICS_NUM_TEXT:
						vo.setAddMechanicsNum(val);
						break;
					case IPFSConstant
							.CURR_BASE_RATES_TEXT:
						vo.setCurrBaseRates(val);
						break;
					case IPFSConstant
							.DESTROY_NUM_TEXT:
						vo.setDestroyNum(val);
						break;
					case IPFSConstant
							.TOTAL_SUPPLY_NUM_TEXT:
						vo.setTotalSupplyNum(val);
						break;
					case IPFSConstant
							.FLUX_RATES_TEXT:
						vo.setFluxRates(val);
						break;
					case IPFSConstant
							.LAST_PRICE_TEXT:
						vo.setLastPrice(val);
						break;
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return vo;
	}

	private static String getNumber(String val) {
		String regEx = "[^0-9]";
		Pattern p = Pattern.compile(regEx);
		Matcher m = p.matcher(val);
		return m.replaceAll("").trim();
	}
}
